<?php
/**
 * Created by PhpStorm.
 * User: zhangbing
 * Date: 2017/5/20
 * Time: 16:16
 */
namespace app\service;
use app\models\Models;

class Rsa{
    /**
     * 生成密钥
     * @param string $equipment
     * @throws \Exception
     * @return string $publicKey
     */
    public function generateKey($equipment){
        $rsa = new Models('rsa_key');
        $publicKey = $rsa->getValue(['equipment' => $equipment],'public_key'); #有公钥则直接返回
        if(!$publicKey){
            $key = openssl_pkey_new(['private_key_bits' => 2048]); #加密串长度，此处必须int型
            if(!$key){
                throw new \LogicException('生成密钥失败',1003);
            }
            openssl_pkey_export($key, $privateKey);   #提取私钥
            $arrKey = openssl_pkey_get_details($key); #生成公钥
            $publicKey = $arrKey["key"];
            $time = time();
            $sql  = "insert ignore into it_rsa_key values('','$equipment','{$publicKey}','{$privateKey}',$time)";
            $bool = $rsa->execute($sql);    #数据插入数据库
            if(!$bool){
                throw new \LogicException('操作失败',1010);
            }
            /*//队列处理
            $sql = "insert ignore into it_rsa_key values('','$equipment','{$publicKey}','{$privateKey}',$time)";
            $redis = new \app\service\Redis();
            $len = $redis->inQue('rsa_key',$sql);
            if($len){
                for($i=0;$i<$len;$i++){
                    $pop = $redis->outQue('rsa_key');
                    #数据插入数据库
                    $bool = $rsa->execute($pop);
                    if(false === $bool){
                        throw new \LogicException('操作失败',1010);
                    }
                }
            }
            return true;*/
        }
        return $publicKey;
    }

    /**
     * 数据解密
     * @param string $equipment
     * @param json string $encrypt
     * @throws \Exception
     * @return array $decrypted
     */
    public function decrypt($equipment,$encrypt){
        $rsa = new Models('rsa_key');
        $privateKey = $rsa->getValue(['equipment' => $equipment],'private_key'); #获取私钥
        if(!$privateKey){
            throw new \LogicException('获取私钥失败',1004);
        }
        openssl_private_decrypt(base64_decode($encrypt), $decrypted, $privateKey); #私钥解密
        if(!$decrypted){
            throw new \LogicException('解密失败',1005);
        }
        return (array)json_decode($decrypted);
    }

    /**
     * 数据加密
     * @param $publicKey
     * @param $data
     * @return string
     */
    public function encrypt($publicKey,$data){
        openssl_public_encrypt(json_encode($data), $encrypted, $publicKey);
        return base64_encode($encrypted);
    }
}